using Cysharp.Threading.Tasks;
using Framework.Helper;
using Framework.StateMechine;
using UnityEngine;
using UnityEngine.Networking;

namespace Game.Hotfix
{
    public class HotfixDownloadRemote2Local : StateBase
    {
        private Game.Hotfix.Hotfix hotfix;
        private float duration = 1f;
        // private HotfixArgs args;
        
        public override async UniTask OnEnter(StateArgs _args)
        {
            Debug.Log($"download remote 2 local.");
            
            hotfix = stateMachine.owner as Game.Hotfix.Hotfix;
            await base.OnEnter(_args);
            
            await Download();
            
            stateMachine.Change(HotfixState.Result, args);
        }

        private async UniTask Download()
        {
            float downloadedSize = 0;
            int currentDownloadSize = 0;
            float downBytesPerSecond = 0;
            float span = 0;
            float offset = 0;
            string speed = "";

            foreach (ChecksumData cd in hotfix.downLoadList)
            {
                string url = $"{hotfix.hotfixServerDto.url}?version={hotfix.hotfixServerDto.version}&res={cd.filename}";
                Debug.Log($"[PatchDownloader] download => url: {url} start to load");
                
                DownloadHandler handler = new DownloadHandlerBuffer();
                UnityWebRequest request = new UnityWebRequest(url, "GET", handler, null);
                request.timeout = 60;       // 设置超时时间
                await request.SendWebRequest();   // 发送请求
                
                while (!handler.isDone)
                {
                    // viewUpdate(LauncherViewCMD.UpdateProgress, (downloadedSize + request.downloadedBytes) / this.info.size);
                
                    await UniTask.Yield();

                    offset += (request.downloadedBytes - downBytesPerSecond) <= 0 ? 0 : (request.downloadedBytes - downBytesPerSecond);

                    if (Time.time - span > duration)
                    {
                        speed = getSpeed(offset, Time.time - span);
                        span = Time.time;
                        offset = 0;
                    }

                    float totalSize = hotfix.downloadSize / 1024 / 1024;
                    float currentSize = (downloadedSize + request.downloadedBytes) / 1024 / 1024;

                    // viewUpdate(LauncherViewCMD.UpdateProgressMsg, string.Format("{0:0}MB/{1:0}MB ({2})", currentSize, totalSize, speed));

                    downBytesPerSecond = request.downloadedBytes;
                }
                
                if(request.result == UnityWebRequest.Result.ConnectionError)
                {
                    // viewUpdate(LauncherViewCMD.DonwoadNetError, this.localizeFunc("Launcher_Name_14"));
                    // state = DownloaderState.Error;
                    args = new HotfixArgs()
                    {
                        arg = "网络错误，下载远程资源失败",
                        errorCode = HotfixDownloadErrorCode.ErrorLoadRemoteResFail,
                    };
                    break;
                }
                
                //这里currentDownloadSize 不能是float型， t.filesize 在转换位float型的时候，会有精度缺失的问题，导致下载失败
                currentDownloadSize = cd.filesize;
                
                byte[] data = handler.data;
                string extension = cd.filename.Substring(cd.filename.LastIndexOf('.'));
                int totalDownloadSize = data.Length - (extension.Equals(AssetBundleHelper.abextension) ? AssetBundleHelper.abOffset : 0);
                Debug.Log($"[PatchDownloader] download <= t.filename: {cd.filename}, extension: {extension}");

                if (totalDownloadSize != currentDownloadSize)
                {
                    Debug.Log("[Hotfix][download] download error : " + cd.filename + " totalDownloadSize: " + totalDownloadSize + " currentDownloadSize : " + currentDownloadSize);
                    // state = DownloaderState.Error;
                    args = new HotfixArgs()
                    {
                        arg = "下载远程资源不完整",
                        errorCode = HotfixDownloadErrorCode.ErrorLoadRemoteSizeFail,
                    };
                    break;
                }
                
                string filename = $"{FileHelper.hotfixFolder}/{cd.filename}";

                HotfixConst.WriteAllBytes(filename, data, 0, data.Length);
                downloadedSize += currentDownloadSize;

                // viewUpdate(LauncherViewCMD.UpdateProgress, downloadedSize / hotfix.downloadSize);
                
                // 记录下载过的资源
                // tempDownloadRecord.record(t.filename, t);
            }
        }
        
        private string getSpeed(float byteLength, float span)
        {
            if (byteLength / span < 1024)
            {
                return $"{byteLength / span:F1}B/s";
            }
            else if (byteLength / 1024 / span <= 1024)
            {
                return $"{byteLength / 1024 / span:F1}KB/s";
            }
            else
            {
                return $"{byteLength / 1024 / 1024 / span:F1}MB/s";
            }
        }
    }
}